package oop.ex3.filemanager.actions;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.LinkedHashSet;
import java.util.TreeSet;

import oop.ex3.messages.*;
import oop.ex3.messages.exception.InvalidHeaderException;

import oop.ex3.filemanager.FMContext;
import oop.ex3.sockets.ClientSocket;

public class PrintAllFiles extends FmAction {
	
	/**
	 * constructor for action
	 * @param context
	 */
	public PrintAllFiles(FMContext context) {
		super(context);
	}

	/**
	 * print all files in the system
	 * @param params - array of command params
	 */
	public void run(String[] params) {
		
		//TODO- error- print what you got or print error?
		
		TreeSet<String> files = new TreeSet<String>();
		LinkedHashSet<InetSocketAddress> servers = _context.getServersSet();
		
		for (InetSocketAddress server : servers){
			ClientSocket s = null;
			try {
				 s = new ClientSocket(new InetSocketAddress(server.getAddress()
						, server.getPort()));
				//add files
				performHandShake(s);
				s.SendMessage(new SimpleMessage(ValidHeaders.WANTALLFILES));
				MessageInterface msg;
				while (!(msg = s.readMessage()).getHeader().
						equals(ValidHeaders.ENDLIST) && 
						!msg.getHeader().equals(ValidHeaders.ERROR)){
					files.add(((FileMessage)msg).getFileName());
				}
				finishSession(s);
				s.closeClientSocket();
				s = new ClientSocket(new InetSocketAddress(server.getAddress()
						, server.getPort()));
				performHandShake(s);
				s.SendMessage(new SimpleMessage(ValidHeaders.WANTSERVERS));
				while (!(msg = s.readMessage()).getHeader().
						equals(ValidHeaders.ENDLIST) && 
						!msg.getHeader().equals(ValidHeaders.ERROR)){
					//TODO does this add it to the list and iterate over it?
					servers.add(((PeerInfoMessage)msg).getPeer());
				}
				s.SendMessage(new SimpleMessage(ValidHeaders.ENDSESSION));
				waitForDone(s);
				finishSession(s);
				s.closeClientSocket();
			} catch (Exception e) {
				//TODO send endsession?
				if (s != null){
					try {
						s.SendMessage(new SimpleMessage
								(ValidHeaders.ENDSESSION));
						s.closeClientSocket();
					} catch (IOException e1){
						
					} catch (InvalidHeaderException e2) {
						
					}
				}
			}
			//TODO see comment above
		} for (String file : files){
			System.out.println(file);
		}
	}

}
